#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
@Project: kubeext-SDS 
@File: disk.py
@Author: admin
@Date: 2022/6/2 14:09 
@desc: 
"""
import os

from testconstant import *
from util import get_random_uuid, getArgparseParam, get_cstor_pool, check_pool_info
from utils.adm_exc.parsers import createDiskParser, registerDiskToK8sParser, resizeDiskParser, showDiskParser, \
    deleteDiskParser, prepareDiskParser, cloneDiskParser, migrateDiskParser
from utils.constant.constant import KUBESDS_TEST_ENV_VALUE, KUBESDS_TEST_ENV_KEY, KUBESDS_LOG
from utils.exception import KubdesdsExecuteException
from utils.logger import set_logger

logger = set_logger(os.path.basename(__file__), KUBESDS_LOG)


def diskTest(disk_uuid, pool_name):
    """
    云盘相关测试
    :param disk_uuid: 云盘uuid
    :param pool_name: 云盘所属存储（此处对应的是数据库中的msid值（界面上可以直接查看），而非表cl_hostlocalstorage_inf对应的poolname）
    :return:
    """
    logger.debug('\n\n')
    logger.debug('***kubesds test disk [%s] start.' % disk_uuid)
    # 设置测试时，特有的环境变量内容
    os.environ[KUBESDS_TEST_ENV_KEY] = KUBESDS_TEST_ENV_VALUE
    try:
        pool_info = get_cstor_pool(pool_name)
        if not pool_info:
            raise KubdesdsExecuteException('kubesdsTestError', 'pool info is none.')
        # 1.通过规格创建无分配策略的2G数据盘
        createDiskTest(disk_uuid, pool_info)
        # 2.注册云盘至k8s中
        registerDiskToK8sTest(disk_uuid, pool_info)
        # 3.云盘路径检查（此处针对云盘id进行云盘路径检查（此时vol必传），若针对路径进行检查（此时无需传vol，且path和pool_info必传））
        prepareDiskTest(domain=None, vol=disk_uuid, path=None)
        # 4.云盘扩容（扩容至4G）
        resizeDiskTest(disk_uuid, pool_info)
        # 5.显示云盘
        showDiskTest(disk_uuid, pool_info)
        # 6.克隆云盘（本次克隆云盘只针对数据盘，不涉及系统盘），且克隆至原始云盘相同的存储池上
        clone_disk_uuid = get_random_uuid()
        cloneDiskTest(disk_uuid, pool_info, clone_disk_uuid)
        # 7.克隆完后随即进行删除
        deleteDiskTest(clone_disk_uuid, pool_info)
        # 8.删除云盘
        deleteDiskTest(disk_uuid, pool_info)
    except Exception as e:
        raise KubdesdsExecuteException('kubesdsTestError', 'disk test error.')
    finally:
        # 去除测试时特有的环境变量内容
        if KUBESDS_TEST_ENV_KEY in os.environ:
            del os.environ[KUBESDS_TEST_ENV_KEY]


def createDiskTest(disk_uuid, pool_info, vol_type=DEFAULT_VOL_TYPE):
    """
    创建云盘测试
    :param disk_uuid: 云盘uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :param vol_type: 默认为数据盘
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)
    vol_format = "qcow2" if pool_type in KUBESDS_TEST_FILE_STORAGE_TYPE else "raw"

    # 默认创建数据云盘，无预分配策略，默认大小为2G
    create_disk_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'preallocation': DEFAULT_PRE_ALLOCATION,
        'capacity': DEFAULT_VOL_CAPACITY,
        'format': vol_format,
        'pool': pool,
        'type': pool_type,
    }
    # 创建云盘
    createDiskParser(getArgparseParam(create_disk_params))

    logger.debug('***kubesds create test disk [%s] success.' % disk_uuid)


def registerDiskToK8sTest(disk_uuid, pool_info, vol_type=DEFAULT_VOL_TYPE):
    """
    注册云盘至k8s测试
    :param disk_uuid: 云盘uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :param vol_type: 默认为数据盘
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)

    register_disk_params = {
        'vol': disk_uuid,
        'pool': pool,
        'volumetype': vol_type
    }
    # 注册云盘
    registerDiskToK8sParser(getArgparseParam(register_disk_params))

    logger.debug('***kubesds register test disk [%s] success.' % disk_uuid)


def prepareDiskTest(domain=None, vol=None, path=None):
    """
    云盘路径检查测试
    针对云盘id进行云盘路径检查（此时vol必传），若针对路径进行检查（此时无需传vol，且path和pool_info必传）
    :param domain: 云盘挂载的云主机
    :param vol: 云盘uuid
    :param path: 云盘路径
    :return:
    """

    prepare_disk_params = {
        'vol': vol,
        'domain': domain,
        'path': path,
    }

    if vol:
        # 通过云盘id进行路径检查时（此时不用区分云盘所属存储类型），其余参数置空
        prepare_disk_params['path'] = None
        prepare_disk_params['domain'] = None
    elif path:
        # 通过云盘路劲进行检查时，此处只考虑检查文件系统类型的云盘路径检查（路径以"/"开头），ceph-dev不涉及
        if not path.startswith('/'):
            prepare_disk_params = None
        else:
            prepare_disk_params['vol'] = None
            prepare_disk_params['domain'] = None
    # 不考虑云盘挂载云主机情况
    else:
        prepare_disk_params = None

    if prepare_disk_params:
        # 检查云盘路径
        prepareDiskParser(getArgparseParam(prepare_disk_params))

        logger.debug('***kubesds prepare test disk success.')


def resizeDiskTest(disk_uuid, pool_info, vol_type=DEFAULT_VOL_TYPE):
    """
    云盘扩容测试
    :param disk_uuid: 云盘uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :param vol_type: 默认为数据盘
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)

    resize_disk_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'capacity': RESIZE_VOL_CAPACITY,
        'pool': pool,
        'type': pool_type,
    }
    # 扩容云盘
    resizeDiskParser(getArgparseParam(resize_disk_params))

    logger.debug('***kubesds resize test disk [%s] success.' % disk_uuid)


def showDiskTest(disk_uuid, pool_info, vol_type=DEFAULT_VOL_TYPE):
    """
    云盘显示测试
    :param disk_uuid: 云盘uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :param vol_type: 默认为数据盘
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)

    show_disk_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'pool': pool,
        'type': pool_type,
    }
    # 显示云盘
    showDiskParser(getArgparseParam(show_disk_params))

    logger.debug('***kubesds show test disk [%s] success.' % disk_uuid)


def deleteDiskTest(disk_uuid, pool_info, vol_type=DEFAULT_VOL_TYPE):
    """
    云盘删除测试
    :param disk_uuid: 云盘uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :param vol_type: 默认为数据盘
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)

    show_disk_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'pool': pool,
        'type': pool_type,
        'fillzero': False,
    }
    # 删除云盘
    deleteDiskParser(getArgparseParam(show_disk_params))

    logger.debug('***kubesds delete test disk [%s] success.' % disk_uuid)


def cloneDiskTest(disk_uuid, pool_info, clone_disk_uuid, vol_type=DEFAULT_VOL_TYPE):
    """
    克隆云盘测试（本次克隆云盘只针对数据盘，不涉及系统盘），且克隆至原始云盘相同的存储池上
    :param disk_uuid: 云盘uuid
    :param vol_type: 默认为数据盘
    :param clone_disk_uuid: 克隆云盘uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)
    clone_vol_format = "qcow2" if pool_type in KUBESDS_TEST_FILE_STORAGE_TYPE else "raw"
    clone_disk_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'newname': clone_disk_uuid,
        'format': clone_vol_format,
        'pool': pool,
        'type': pool_type,
    }
    # 克隆云盘
    cloneDiskParser(getArgparseParam(clone_disk_params))

    logger.debug('***kubesds clone test disk [%s] success.' % disk_uuid)


def migrateDiskTest(disk_uuid, pool_info, target_pool_info, vol_type=DEFAULT_VOL_TYPE):
    """
    迁移云盘测试（本次克隆云盘只针对数据盘，不涉及系统盘）
    :param disk_uuid: 云盘uuid
    :param vol_type: 默认为数据盘
    :param pool_info: 云盘存储信息，通过cstor show-pool查询云盘所属存储所得信息
    :param target_pool_info: 目标存储信息，通过cstor show-pool查询云盘所属存储所得信息
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    target_pool_type, target_pool = check_pool_info(target_pool_info)

    # 文件类型存储与ceph-dev之间不能相互迁移
    if (pool_type in KUBESDS_TEST_FILE_STORAGE_TYPE and target_pool_type == CEPH_DEV) \
            or (pool_type == CEPH_DEV and target_pool_type in KUBESDS_TEST_FILE_STORAGE_TYPE):
        raise KubdesdsExecuteException('kubesdsTestError', 'migrate not support file to ceph-dev or ceph-dev to file.')

    migrate_disk_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'pool': target_pool,
    }
    # 迁移云盘
    migrateDiskParser(getArgparseParam(migrate_disk_params))

    logger.debug('***kubesds migrate test disk [%s] success.' % disk_uuid)


if __name__ == '__main__':
    # 以下pool值对应的是数据库中的msid值（界面上可以直接查看），而非表cl_hostlocalstorage_inf对应的poolname
    # ------------以下存储一存在于界面-----------------
    LocalFS_pool = '74d2724167034d8ab9244807f20bfbd8'
    NFS_pool = 'd1abfdee97a146f0aab87728f04e379e'
    CephBlock_pool = 'eb3e1a5398254ec8b67df674d00c4baa'
    SandStone_pool = '7cddd1df93d649a3852f31d89111822a'
    # ----------------------------------------------
    diskTest(get_random_uuid(), SandStone_pool)
